GtkStateFlags old_state);
static void gtk_widget_real_queue_draw_region (GtkWidget *widget,
const cairo_region_t *region);
+static void gtk_widget_real_queue_draw_child (GtkWidget *widget,
+ GtkWidget *child,
+ const cairo_region_t *region);
static AtkObject* gtk_widget_real_get_accessible (GtkWidget *widget);
static void gtk_widget_accessible_interface_init (AtkImplementorIface *iface);
static AtkObject* gtk_widget_ref_accessible (AtkImplementor *implementor);
klass->adjust_size_allocation = gtk_widget_real_adjust_size_allocation;
klass->adjust_baseline_allocation = gtk_widget_real_adjust_baseline_allocation;
klass->queue_draw_region = gtk_widget_real_queue_draw_region;
+ klass->queue_draw_child = gtk_widget_real_queue_draw_child;
widget_props[PROP_NAME] =
g_param_spec_string ("name",
*****************************************/
static void
-gtk_widget_real_queue_draw_region (GtkWidget *widget,
+gtk_widget_real_queue_draw_child (GtkWidget *widget,
+ GtkWidget *child,
+ const cairo_region_t *child_region)
+{
+ GdkWindow *child_window, *window;
+ cairo_region_t *region;
+
+ window = gtk_widget_get_window (widget);
+ child_window = gtk_widget_get_window (child);
+
+ if (child_window == window)
+ gtk_widget_queue_draw_region (widget, child_region);
+
+ region = cairo_region_copy (child_region);
+ while (child_window != window && !cairo_region_is_empty (region))
+ {
+ int x, y;
+
+ /* clip to current window */
+ cairo_region_intersect_rectangle (region, &(GdkRectangle) {
+ 0, 0,
+ gdk_window_get_width (child_window),
+ gdk_window_get_height (child_window)});
+
+ /* make region relative to next window */
+ gdk_window_get_position (child_window, &x, &y);
+ cairo_region_translate (region, x, y);
+ child_window = gdk_window_get_parent (child_window);
+ }
+
+ gtk_widget_queue_draw_region (widget, region);
+ cairo_region_destroy (region);
+}
+
+static void
+gtk_widget_queue_draw_child (GtkWidget *parent,
+ GtkWidget *child,
+ const cairo_region_t *region)
+{
+ WIDGET_CLASS (parent)->queue_draw_child (parent, child, region);
+}
+
+static void
+gtk_widget_real_queue_draw_region (GtkWidget *widget,
const cairo_region_t *region)
{
- GtkWidgetPrivate *priv = widget->priv;
+ GtkWidget *parent = _gtk_widget_get_parent (widget);
+
+ if (parent == NULL)
+ return;
- gdk_window_invalidate_region (priv->window, region, TRUE);
+ gtk_widget_queue_draw_child (parent, widget, region);
}
/**
gtk_widget_queue_draw_region (GtkWidget *widget,
const cairo_region_t *region)
{
- GtkWidget *w;
-
g_return_if_fail (GTK_IS_WIDGET (widget));
if (cairo_region_is_empty (region))
return;
- /* Just return if the widget or one of its ancestors isn't mapped */
- for (w = widget; w != NULL; w = w->priv->parent)
- if (!_gtk_widget_get_mapped (w))
- return;
+ /* Just return if the widget isn't mapped */
+ if (!_gtk_widget_get_mapped (widget))
+ return;
WIDGET_CLASS (widget)->queue_draw_region (widget, region);
}
* @adjust_baseline_request:
* @adjust_baseline_allocation:
* @queue_draw_region: Invalidates the area of widget defined by
- * region by calling gdk_window_invalidate_region() on the widget's
- * window and all its child windows.
+ * region.
+ * @queue_draw_child: Child wants to be redrawn. The region given is in
+ * the child's coordinate system.
*/
struct _GtkWidgetClass
{
void (* adjust_baseline_request)(GtkWidget *widget,
gint *minimum_baseline,
gint *natural_baseline);
- void (* adjust_baseline_allocation) (GtkWidget *widget,
- gint *baseline);
- void (*queue_draw_region) (GtkWidget *widget,
- const cairo_region_t *region);
+ void (* adjust_baseline_allocation) (GtkWidget *widget,
+ gint *baseline);
+ void (* queue_draw_region) (GtkWidget *widget,
+ const cairo_region_t *region);
+ void (* queue_draw_child) (GtkWidget *widget,
+ GtkWidget *child,
+ const cairo_region_t *region);
GskRenderNode *(* get_render_node) (GtkWidget *widget,
GskRenderer *renderer);
static void gtk_window_style_updated (GtkWidget *widget);
static void gtk_window_state_flags_changed (GtkWidget *widget,
GtkStateFlags previous_state);
+static void gtk_window_queue_draw_region (GtkWidget *widget,
+ const cairo_region_t *region);
static GSList *toplevel_list = NULL;
static guint window_signals[LAST_SIGNAL] = { 0 };
widget_class->state_flags_changed = gtk_window_state_flags_changed;
widget_class->style_updated = gtk_window_style_updated;
widget_class->get_render_node = gtk_window_get_render_node;
+ widget_class->queue_draw_region = gtk_window_queue_draw_region;
container_class->remove = gtk_window_remove;
container_class->check_resize = gtk_window_check_resize;
update_themed_icon (GTK_WINDOW (widget));
}
+static void
+gtk_window_queue_draw_region (GtkWidget *widget,
+ const cairo_region_t *region)
+{
+ if (_gtk_widget_get_parent (widget))
+ {
+ GTK_WIDGET_CLASS (gtk_window_parent_class)->queue_draw_region (widget, region);
+ return;
+ }
+
+ gdk_window_invalidate_region (_gtk_widget_get_window (widget), region, TRUE);
+}
+
/**
* _gtk_window_unset_focus_and_default:
* @window: a #GtkWindow